import datetime
import uuid
from flask import Flask, request, current_app
import logging
import json
from easydict import EasyDict
import paddle
from paddlespeech.cli import ASRExecutor,TextExecutor,TTSExecutor

def create_app():
    app = Flask(__name__, static_folder='static', static_url_path='/static')
    # 日志
    app.debug = True
    handler = logging.FileHandler('speech_flask.log', encoding='UTF-8')
    handler.setLevel(
        logging.DEBUG
    )  
    # 设置日志记录最低级别为DEBUG，低于DEBUG级别的日志记录会被忽略，不设置setLevel()则默认为NOTSET级别。
    logging_format = logging.Formatter(
        '%(asctime)s - %(levelname)s - %(filename)s - %(funcName)s - %(lineno)s - %(message)s'
    )
    handler.setFormatter(logging_format)
    app.logger.addHandler(handler)
    app.logger.info('启动 AI 语音服务..')
    return app

app = create_app()

asr_executor = ASRExecutor()

text_executor = TextExecutor()

def request_parse(req_data):
    if req_data.method == 'POST':
        data = req_data.json
    elif req_data.method == 'GET':
        data = req_data.args
    return data

def get_uuid():
    uid = str(uuid.uuid4())
    return ''.join(uid.split('-'))

def init_result(ret, msg=''):
    result = EasyDict()
    result.ret = ret
    result.msg = msg
    return result


def result_success(data, msg):
    res = init_result(200, msg)
    res.data = data
    return json.dumps(res, ensure_ascii=False)


def result_success_msg(msg):
    res = init_result(200, msg)
    return json.dumps(res, ensure_ascii=False)

def result_error(msg):
    res = init_result(400, msg)
    return json.dumps(res, ensure_ascii=False)

# ping
@app.route('/api/ping', methods=['GET', 'POST'])
def ping():
    return result_success_msg('ai voice service pong')


@app.route('/api/voice2text', methods=['POST','GET'])
def voice2text():
    try:
        req = request_parse(request)
        wav_path = req.get("wavPath")        
        if wav_path is None or wav_path == '':
            wav_path = './yiyi.wav'

        # 语音转文本
        text = asr_executor(
        model='conformer_wenetspeech',
        lang='zh',
        sample_rate=16000,
        config=None,  # Set `config` and `ckpt_path` to None to use pretrained model.
        ckpt_path=None,
        audio_file=wav_path,
        force_yes=True,
        device=paddle.get_device())

        # 处理标点符号
        result = text_executor(
            text=text,
            task='punc',
            model='ernie_linear_p7_wudao',
            lang='zh',
            config=None,
            ckpt_path=None,
            punc_vocab=None,
            device=paddle.get_device()) 

        return result_success(result, '处理成功')
    except Exception as ex:
        current_app.logger.error(ex)
        return result_error('处理失败')

@app.route('/api/text2voice', methods=['POST','GET'])
def text2voice():
    try:
        # 检查参数
        req = request_parse(request)
        text = req.get("text")   
        am = req.get("am")   
        print('输入文本：',text)
        if text is None or text == '':
            text = '今天天气真好啊！'
        if am is None or am == '':
            am = 'speedyspeech_csmsc'

        out_file_name = get_uuid()
        tts_executor = TTSExecutor()
        wav_file = tts_executor(
            text=text,
            output='./static/{0}.wav'.format(out_file_name),
            am=am,
            am_config=None,
            am_ckpt=None,
            am_stat=None,
            spk_id=0,
            phones_dict=None,
            tones_dict=None,
            speaker_dict=None,
            voc='pwgan_csmsc',
            voc_config=None,
            voc_ckpt=None,
            voc_stat=None,
            lang='zh',
            device=paddle.get_device())

        return result_success('/static/{0}.wav'.format(out_file_name), '处理成功')
    except Exception as ex:
        current_app.logger.error(ex)
        return result_error('处理失败')

if __name__ == "__main__":    
    app.run(host='127.0.0.1', port=8080) 